MindStudio 算子开发工具链包含多种工具。本文档以开发一个简单加法算子为例,带您贯穿算子开发全流程,直观体验工具链带来的高效与便捷。
体验地图 (核心操作仅需 10 分钟)
[object Object]
[object Object]
执行如下指令,确认系统输出正确的芯片 SoC 型号(如 910B4、910_9392):
[object Object]
执行以下命令,若输出 "All is OK",则表明所需 Python 包及其版本均满足规范:
执行以下命令,若能正常列出目录内容,则说明代码仓已正确就位:
首先,进行算子算法设计。借助 msKPP 工具,可在秒级时间内获得算子性能建模结果,在无硬件条件下预估性能,快速验证实现方案的可行性。先跟着操作体验效果,原理部分可稍后阅读:
[object Object]
创建子工作区目录
[object Object]开发 Python 脚本
[object Object]
因是快速入门,将准备好的 msKPP 的 DSL 脚本复制到此即视为开发完成(本教程聚焦工具链使用,实际开发需自行实现):
[object Object]
执行 Python 脚本开始性能建模,如果成功,将自动在当前目录下生成 "MSKPP{timestamp}" 结果目录:
如果脚本报错,提示 Chip is unsupported,请确认环境变量 [object Object] 是否正确设置,如变量为空,请参考正确设置。
生成如下结果目录:
以 Instruction_statistic.csv 为例,其内容如下:
由上述内容可见,MOV-UB_TO_GM(从 UB 搬移到 GM)的耗时(Duration)最长,指令周期数(Cycle)也最多,是性能优化中需重点关注的关键路径。在实际开发中,如果发现此类内存搬运耗时占比过高,应优先考虑优化数据复用(Tiling)或使用更高效的搬运指令。
算法设计完成后,即可进入算子代码编写阶段。算子工程较为复杂且包含大量框架代码,msOpGen 工具可自动生成完整的算子工程框架,使开发者聚焦于核心算法实现,避免在项目搭建、编译配置等重复性工作上耗费时间。先跟着操作体验效果,原理部分可稍后阅读:
创建子工作区目录
创建名为
[object Object]的子目录,作为算子源码根目录,后续所有源码操作均基于此路径开展:[object Object]开发算子定义配置文件
[object Object]
因是快速入门,将准备好的配置文件拷贝到此即视为开发完成(本教程聚焦工具链使用,实际开发需自行实现):
[object Object]基于配置生成代码框架
执行以下命令生成 Ascend C 算子工程,参数说明:-lan cpp 表明要生成 Ascend C 代码;-c 为芯片 SoC 型号(不同芯片处理上可能有区别):
[object Object]查看生成的结果
[object Object]
生成的工程结构看起来庞大而复杂,但我们仅需关注标记为【用户扩展点】的三个C++文件,其余均为框架代码,无特殊需求无需查看修改:
[object Object]
[object Object]
在上述三个【用户扩展点】文件中实现具体算法逻辑。因是快速入门,将准备好的 3 个 C++ 文件拷贝到此即视为开发完成(本教程聚焦工具链使用,实际开发需自行实现核心逻辑):
编译算子
执行构建脚本,成功后将在 build_out 目录下生成 .run 格式的算子部署包(sed 命令用于规避某些环境下的并发 pipe 问题,将打包改为串行):
[object Object]部署算子
[object Object]
因各平台生成的算子部署包名称略有差异,执行以下脚本以自动定位并运行部署包(在固定环境中,实际等效于执行类似 ./build_out/custom_opp_ubuntu_aarch64.run 的命令):
[object Object]加入动态库路径
部署成功后,按终端提示追加算子依赖的动态库路径:
[object Object]
[object Object]
执行算子调用工程,验证算子功能(本例执行 1.0 + 2.0,预期结果为 3.0):
若输出如下内容,结果为 3.0,则表明算子已成功加载并计算正确:
若超过 30 秒未返回结果,可能是 NPU 卡繁忙,可按 Ctrl+C 终止后切换至其他空闲卡重试;若出现类似如下错误,可能原因包括:NPU卡异常(硬件故障、驱动问题等),/dev/hisi_hdc 设备异常(如容器内未成功挂载、缺乏访问权限、因线程数过多导致设备无法打开等),以及内存等系统资源不足等。
错误码说明请参见:,请先解决 NPU 卡故障或更换为其他正常卡后再继续体验(指定 NPU 卡运行的方法详见上文“关于 NPU 设备选择的说明”):
后续 3 个工具的执行都需要修改此 CMakeLists.txt,保留此备份,用于恢复环境:
算子开发完成后,可借助 msSanitizer 工具检测是否存在内存越界、竞争条件、未初始化变量或同步异常等严重运行时缺陷,从而高效定位潜在的隐蔽性错误。先跟着操作体验效果,原理部分可稍后阅读:
为启用检测能力,需在 Kernel 侧的 CMakeLists.txt 首行插入 sanitizer 编译选项,注入检测桩代码:
将准备好的含缺陷代码的源文件覆盖原始实现,人为引入越界访问:
关键修改如下(2 * this->tileLength 试图读取 2 倍长度,超出 GM 内存中 xGm 的分配范围,触发 “非法读取”):
工具输出如下错误报告,则表明已成功执行:
- illegal read of size 224:表示非法读取了 224 字节。
- op_kernel/add_custom.cpp:44:9:表明越界访问发生在 add_custom.cpp 第 44 行。
为后续工具使用做准备,回退手工修改:
若算子功能异常,可借助 msDebug 工具进行断点调试,高效定位问题。先跟着操作体验效果,原理部分可稍后阅读:
[object Object]
确认内核调试开关 debug_switch 是否打开:
若输出值不为 1,请使用 root 权限执行以下命令 (有条件最好在宿主机中执行,某些场景容器内设置成功实际并不能生效):
如果不能成功设置为 1,msDebug 功能不可用,只能跳过此节 msDebug 的体验。
修改编译选项
在 Kernel 侧 CMakeLists.txt 首行插入配置,用于启用调试信息、禁用编译优化:
[object Object]重新编译部署算子
[object Object]
通过脚本设置 LAUNCH_KERNEL_PATH,指定算子obj加载路径并导入调试符号信息:
启动调试器
[object Object]设置断点
待 (msdebug) 提示符出现后,设置断点于 add_custom.cpp 第 34 行:
[object Object][object Object]
运行算子
输入 run 启动程序,等待命中断点:
[object Object]显示如下信息,则成功命中断点:
[object Object]查看变量的值
在断点处执行以下命令,显示当前作用域内的所有局部变量:
[object Object]退出调试器
[object Object]
为后续工具使用做准备,回退手工修改:
若算子性能未达预期,可借助 msOpProf 工具采集运行时性能数据,进行深入分析与优化,确保算子在不同昇腾硬件平台上高效执行。先跟着操作体验效果,原理部分可稍后阅读:
修改编译选项
在 Kernel 侧 CMakeLists.txt 首行插入一行配置,开启调试信息:
[object Object][object Object]
重新编译部署算子
[object Object]
[object Object]
上板性能采集
[object Object]仿真器性能采集
[object Object]
[object Object]
工具在指定 --output 目录下生成 .csv 和 .bin 格式的结果文件,若输出未报错,则表明执行成功:
csv 文件
例如 MemoryUB.csv,打开可以看到如下信息:
数据显示任务被均分为 8 个 block,全部调度至 Vector Core 执行。例如 Block 0 的带宽(1.02 GB/s)明显高于 Block 1(0.77 GB/s),如果差异过大,可能提示存在优化空间:[object Object]undefined
bin 文件
可使用[object Object]工具打开,以图形化方式直观展示各类性能视图,例如:计算内存热力图、Cache 热力图以及算子代码热点图等。[object Object]
为后续工具使用做准备,回退手工修改:
恭喜您完成算子开发工具链入门体验。
至此,您已完整走通“设计 → 开发 → 检测 → 调试 → 调优”的算子开发全流程,并实际体验了以下五个核心工具的基本用法:
如果您想继续进阶体验,可参考以下步骤:
第一步:巩固基础 —— 独立开发一个新算子
参考本教程中的 AddCustom,尝试独立实现一个减法算子(SubCustom)或乘法算子(MulCustom),重点关注:Tiling 策略的设计差异、不同计算指令(如 [object Object]、[object Object])的使用,以及端到端的编译部署流程。
第二步:深入工具 —— 掌握各工具的高级功能
本教程仅覆盖了各工具的入门用法,每个工具都提供了更丰富的高级能力,建议按需访问对应仓的《使用指南》等深入学习:
第三步:落地真实业务 —— 从教学走向生产
深入研读,系统掌握多级流水、数据排布、内存管理等核心概念,在此基础上尝试将工具链应用于实际业务算子的开发与调优,逐步构建从原型验证到生产级交付的完整能力。
问题现象
问题原因
[object Object] 环境变量丢失。
解决方法
问题现象
问题原因
算子部署时没有将 op_api/include/aclnn_add_custom.h 部署到正确位置,导致找不到头文件。一种可能的原因是环境中存在环境变量 [object Object],且其值不正确或包含多个以冒号间隔的路径,但部署头文件时只会成功拷贝到第一个路径,后续目录均未部署。
解决方法
删除该环境变量(执行 [object Object]),然后重新部署算子。
问题现象
问题原因
部署完算子后,没有按输出提示将 so 加入环境变量 LD_LIBRARY_PATH 中。
解决方法
按第 3 步,重新设置 LD_LIBRARY_PATH 环境变量。
问题现象
问题原因
指定的断点行可能是空行或注释等无法设置断点的行,或者 [object Object] 没有成功设置,原因参考下节说明。
解决方法
查看代码源文件,确认代码的真实行号;按 以 root 权限在宿主机上(注意不是容器内)设置 [object Object] = 1。
问题现象
问题原因
没有成功设置[object Object]。确认宿主机上是否被修改回0了,或者若您在云服务商提供的容器环境中操作的,这种场景即使在容器内成功将 [object Object] 设置并查询为 1,
该状态也可能是虚假的。因出于安全考虑,底层宿主机通常会通过写时复制(CoW)、影子文件或覆盖挂载(overlay mount)等机制对 /proc 目录进行隔离,导致设置未实际生效。
解决方法
以 root 权限登录到宿主机上(注意不是容器内),按 设置 [object Object] = 1,如果不能设置成功只能跳过此工具体验。